package com.uu.it.tracker.views;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.android.tracker.R;
import com.android.tracker.R.drawable;
import com.android.tracker.R.id;
import com.android.tracker.R.layout;
import com.uu.it.tracker.computation.CalculationRunable;
import com.uu.it.tracker.computation.Calculator;
import com.uu.it.tracker.computation.RecordCalculator;
import com.uu.it.tracker.db.DBAdapter;
import com.uu.it.tracker.gps.Gps;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class RunView extends Activity{
	/**
	 * Whether the start button has been pressed already.
	 * */
	boolean isStart = false; 
	
	/**
	 * Whether the finished button has been pressed already.
	 * */
	public static boolean isFinished;
	
	/**
	 * Thread responses to communicate with sensor node and calculate data
	 * */
	Thread calculationThread;
	
	/**
	 * record content and calculator
	 * */
	RecordCalculator record;
	
	/**
	 * needle view
	 */
	private ImageView needle ;
	
	/**
	 * digital place of ten
	 */
	private ImageView dten ;
	
	/**
	 * digital place of unit
	 */
	private ImageView dunit ;
	
	/**
	 * Button start
	 */
	private Button startButton;
	
	/**
	 * Button finish
	 */
	private Button finishButton;
	
	/**
	 * Array with instant speed, km/h
	 */
	private List<Integer> allSpeed = new ArrayList();
	
	/**
	 * GPS service
	 */
	ComponentName myGps;
	
	/**
	 * click listener of start button
	 * */
	private OnClickListener startButtonListener = new OnClickListener(){
		/**
		 * Create a calculation thread once the start button is clicked. 
		 * */
		public void onClick(View v){
			if(!isStart) {
				isStart = true;
				isFinished = false;
				
				// myGps = startService(new Intent(RunView.this,Gps.class));
				
				CalculationRunable cRunable = new CalculationRunable(handler);
				calculationThread = new Thread(cRunable);
				calculationThread.start();
				
				record = new RecordCalculator();
				record.setStartTime();
				record.setDate();
				
				allSpeed.clear();
			
				v.setEnabled(false);
				finishButton.setEnabled(true);
			}
			return;
		}
	};
	
	/**
	 * click listener of finish button
	 * */
	private OnClickListener finishButtonListener = new OnClickListener(){
		/**
		 * Create a calculation thread once the start button is clicked. 
		 * */
		public void onClick(View v){
			if(!isFinished && isStart) {
				isFinished = true;
				isStart = false;
				record.setFinishTime();
				record.computeDistance();
				v.setEnabled(false);
				startButton.setEnabled(true);
				
				/*try {
					Class gpsClass = Class.forName(myGps.getClassName());
					stopService(new Intent(RunView.this,gpsClass));
				}catch(ClassNotFoundException e){
					Log.i("gps", "GPS class not found");
				}*/
				
				//insert record into database
				Insert2DB();
				
				//send allSpeed to speed graph
				Intent it = new Intent(RunView.this,SpeedGraphView.class);
				Bundle speedBundle = new Bundle();
				
				int[] fs = new int[allSpeed.size()];
				for(int i = 0; i < allSpeed.size(); ++i){
					fs[i] = allSpeed.get(i).intValue();
				}
				speedBundle.putIntArray("speed", fs);
				speedBundle.putInt("maxSpeed", record.maxSpeed());
				
				it.putExtras(speedBundle);
				startActivity(it);
			}
			return;
		}
	};
	
	/**
	 * Handler of the message queue of this thread
	 * */
	private Handler handler = new Handler() {
		public void handleMessage(Message msg){
			//update the interface once informed by the calculation thread
			Bundle dataBundle = msg.getData();
			Calculator.SportStatus data = 
				dataBundle.getParcelable(CalculationRunable.key);
			
			//should update the interface with these data
			
			UpdateStatus(data.getStatus());
			
			float speed = data.getSpeed();
			UpdateSpeed(speed);
			allSpeed.add((int)(speed*3.6+0.5));
			record.incrementSpeed(speed);
		}

	};

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

       
	}
	
	protected void onStart() {
		super.onStart();
		 setContentView(R.layout.runview);
	        
	        //register startListener to button01
	        startButton = (Button)findViewById(R.id.Start);
	        startButton.setOnClickListener(startButtonListener);
	        
	        
	        //register finishListener to button02
	        finishButton = (Button)findViewById(R.id.Finish);
	        finishButton.setOnClickListener(finishButtonListener);
	        
	        
	        needle = (ImageView)this.findViewById(R.id.Needle);
	        dten = (ImageView)this.findViewById(R.id.Digital1);
	        dunit = (ImageView)this.findViewById(R.id.Digital2); 
	}

	protected void Insert2DB() {
		// TODO Auto-generated method stub
		DBAdapter db = new DBAdapter(this);
		db.open();
		db.insertHistory(record.date, record.startTime, record.finishTime, ""+record.distance,
				""+record.avarageSpeed(), ""+record.maxSpeed());	
		db.close();
	}

	/**
	 * update the speed in the interface. 
	 * the float speed is m/s, should change it into km/h
	 * @param speed
	 */
	protected void UpdateSpeed(float speed) {
		// TODO Auto-generated method stub
		//transit m/s to km/h and get the upper value
		//the digit will show 01 unless the speed is greater than 0.138m/s
		//average walk 1.2m/s, average run 6.7m/s
		int myspeed = (int) (speed * 3.6 + 0.5);
		//place of ten
		int d1 = myspeed/10;
		//place of unit
		int d2 = myspeed%10;
		
		//set place of ten
		switch (d1){
		case 0:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_0));
			break;
		case 1:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_1));
			break;
		case 2:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_2));
			break;
		case 3:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_3));
			break;
		case 4:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_4));
			break;
		case 5:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_5));
			break;
		case 6:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_6));
			break;
		case 7:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_7));
			break;
		case 8:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_8));
			break;
		case 9:
			dten.setImageDrawable(getResources().getDrawable(R.drawable.numeral_9));
			break;
		}
		
		//set place of unit
		switch (d2){
		case 0:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_0));
			break;
		case 1:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_1));
			break;
		case 2:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_2));
			break;
		case 3:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_3));
			break;
		case 4:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_4));
			break;
		case 5:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_5));
			break;
		case 6:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_6));
			break;
		case 7:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_7));
			break;
		case 8:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_8));
			break;
		case 9:
			dunit.setImageDrawable(getResources().getDrawable(R.drawable.numeral_9));
			break;
		}
	}
	
	/**
	 * update the needle
	 * @param status
	 */
	protected void UpdateStatus(String status) {
		// TODO Auto-generated method stub
		
		if (status.equals(Calculator.STANDING)) {
			needle.setImageDrawable(getResources().getDrawable(R.drawable.needle_stand));
		}
		if (status.equals(Calculator.WALKING)){
			needle.setImageDrawable(getResources().getDrawable(R.drawable.needle_walk));
		}
		if (status.equals(Calculator.RUNNING)){
			needle.setImageDrawable(getResources().getDrawable(R.drawable.needle_run));
		}
	}
	
}
